using GrapeCity.Forguncy.Commands;
using GrapeCity.Forguncy.Log;
using GrapeCity.Forguncy.Plugin;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text.Json;
using System.Threading.Tasks;

namespace FaissOperation
{
    [Icon("pack://application:,,,/FaissOperation;component/Resources/Icon.png")]
    [Designer("FaissOperation.Designer.FaissOperationServerCommandDesigner, FaissOperation")]
    [Category("嵌入式向量索引")]
    [OrderWeight(800)]
    public class Cluster_Load : Command, ICommandExecutableInServerSideAsync
    {
        [FormulaProperty]
        [DisplayName("集合名")]
        public object KBName { get; set; }

        [ComboProperty]
        [DisplayName("集合的类型")]
        [Description("内建的向量索引：适用于小规模数据，不依赖第三方类库；FAISS的Flat索引：适用于小规模数据，无需训练，但需配置faiss类库文件；FAISS的IVF索引：比FLAT的查询性能更强，适用于中等规模数据，但维护向量条目时需要训练时间。")]
        public CollectionType CollectionType { get; set; } = CollectionType.Lite;

        [FormulaProperty]
        [DisplayName("向量维度")]
        [Description("集合中存储的向量的维度数量。为了提升性能，请将其设置为4的整数倍。如指定导入的配置，以后者为准。")]
        public object Dimension { get; set; } = 1024;


        [FormulaProperty]
        [DisplayName("簇数（限Faiss IVF）")]
        [Description("集合中索引的簇数，集合中向量越多、差异越大，簇数通常需要更大，如10万个语义向量，推荐设置为128。")]
        public object Nlist { get; set; } = 128;

        [FormulaProperty]
        [DisplayName("集合的配置和数据（BASE64格式字符串）")]
        [Description("Gzip压缩后的文本，需包含集合的配置和全部数据。")]
        public object KBBASE64 { get; set; }


        [DisplayName("强制重新加载")]
        [Description("如果不勾选，系统会检查该向量集合是否已经被加载，性能更好；勾选则会强制重新加载。")]
        public bool ForceReload { get; set; } = false;

        public async Task<ExecuteResult> ExecuteAsync(IServerCommandExecuteContext dataContext)
        {
            var name = (await dataContext.EvaluateFormulaAsync(KBName))?.ToString() ?? "";
            var dim = (await dataContext.EvaluateFormulaAsync(Dimension))?.ToString() ?? "1024";
            var base64 = (await dataContext.EvaluateFormulaAsync(KBBASE64))?.ToString() ?? "";

            if (!ForceReload && CollectionManager.Instance.CollectionExists(name))
            {
                dataContext.Log.AppendLine($"向量集合：{name} 已经被加载到内存，本次跳过重新加载。");
                return new ExecuteResult();
            }
            else
            {
                if (!CollectionManager.Instance.CollectionExists(name))
                {
                    CollectionManager.Instance.AddCollection(name, new CollectionMetaData(CollectionType, int.Parse(dim)));
                }

                if (!string.IsNullOrEmpty(base64))
                {
                    var data = GeneralConverter.ToCollectionData(base64);
                    CollectionManager.Instance.GetCollection(name).LoadData(data);
                }

            }


            return new ExecuteResult();
        }

        public override string ToString()
        {
            if (KBName == null)
            {
                return "创建或加载向量集合";
            }
            else {
                return $"创建或加载向量集合（{CollectionType}）";
            }
            
        }

        public override CommandScope GetCommandScope()
        {
            return CommandScope.ExecutableInServer;
        }

    }
}
